package com.example.demo.Service.impl;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.Service.BookService;
import com.example.demo.Service.IDeepSeekService;
import com.example.demo.config.DeepSeekConfig;
import com.example.demo.entity.Book;
import com.example.demo.entity.ChatRequest;
import com.example.demo.entity.ChatResponse;
import com.example.demo.entity.Recommendation;
import com.example.demo.mapper.BookMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DeepSeekServiceImpl implements IDeepSeekService {

    @Autowired
    private DeepSeekConfig deepSeekConfig;

    @Autowired
    private BookService bookService;

    @Resource
    private BookMapper bookMapper;

    @Override
    public Recommendation generateResponse(String bookTitle) {
        try {
            // 1. 去除书名中的《》字符
            String cleanedBookTitle = bookTitle.replace("《", "").replace("》", "");

            List<Book> allBooks = bookService.getAllBooks();

            // 2. 查找目标书
            Book targetBook = allBooks.stream()
                    .filter(book -> book.getName().equalsIgnoreCase(cleanedBookTitle))
                    .findFirst()
                    .orElse(null);

            // 3. 如果找不到，直接从热门书籍中推荐一本
            if (targetBook == null) {
                List<Book> hotBooks = bookService.getBorrowRank();
                if (hotBooks.isEmpty()) {
                    return new Recommendation("暂无推荐", "当前图书馆暂无热门书数据，无法推荐");
                }
                Book randomBook = hotBooks.get(new Random().nextInt(hotBooks.size()));

                // 4. 使用 AI 来解释为什么推荐这本书
                String fallbackTitle = randomBook.getName();

                // 构造 AI prompt，要求 AI 给出推荐理由
                StringBuilder systemPrompt = new StringBuilder();
                systemPrompt.append("你是图书馆的智能推荐助手，请根据推荐这本书籍，然后你可以说这是图书馆的热门书籍 输出结构化 JSON 格式如下：\\n")
                        .append("{\\n  \"book\": \"推荐书名\",\\n  \"reason\": \"推荐理由\"\\n}\\n")
                        .append("以下是用户请求的热门书籍：《").append(fallbackTitle).append("》\n");

                List<ChatRequest.Message> messages = new ArrayList<>();
                messages.add(new ChatRequest.Message("system", systemPrompt.toString()));
                messages.add(new ChatRequest.Message("user", "请推荐这本书，并给出推荐理由。"));

                ChatRequest request = ChatRequest.builder()
                        .model(deepSeekConfig.getModel())
                        .temperature(deepSeekConfig.getTemperature())
                        .max_tokens(deepSeekConfig.getMaxTokens())
                        .messages(messages)
                        .build();

                HttpResponse execute = HttpUtil.createRequest(Method.POST, deepSeekConfig.getApiUrl())
                        .body(JSONUtil.toJsonStr(request))
                        .header("Content-Type", "application/json")
                        .header("Authorization", "Bearer " + deepSeekConfig.getApiKey())
                        .header("Accept", "application/json")
                        .execute();

                String resp = execute.body();
                log.info("deepseek response: {}", resp);

                ChatResponse chatResponse = JSONUtil.toBean(resp, ChatResponse.class);
                String content = extractResponse(chatResponse);
                log.info("AI 返回原始内容：{}", content);

                // 删除代码块标记并清理空格
                String cleanJson = content.replace("```json", "").replace("```", "").trim();
                log.info("清理后的JSON内容：{}", cleanJson);

                try {
                    cn.hutool.json.JSONObject jsonObject = cn.hutool.json.JSONUtil.parseObj(cleanJson);
                    // 创建推荐对象并正确设置字段
                    Recommendation recommendation = new Recommendation();
                    recommendation.setTitle(jsonObject.getStr("book"));
                    recommendation.setDescription(jsonObject.getStr("reason"));
                    QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
                    // 去除《》
                    String cleandBookTitle = recommendation.getTitle().replace("《", "").replace("》", "");
                    queryWrapper.like("name", cleandBookTitle);
                    List<Book> books = bookMapper.selectList(queryWrapper);
                    Book book = (books != null && !books.isEmpty()) ? books.get(0) : null;
                    recommendation.setBook(book);
                    log.info("推荐结果：{}", recommendation);
                    log.info("书籍的详情信息{}", book);
                    return recommendation;
                } catch (cn.hutool.json.JSONException e) {
                    log.error("返回内容不是合法的 JSON 格式");
                    return new Recommendation("推荐失败", "返回内容不是合法的 JSON 格式");
                }
            }

            // 4. 查找同类别图书，排除自己
            List<Book> recommendedBooks = allBooks.stream()
                    .filter(book -> book.getCategory().equalsIgnoreCase(targetBook.getCategory()))
                    .filter(book -> !book.getName().equalsIgnoreCase(targetBook.getName()))
                    .limit(10)
                    .collect(Collectors.toList());

            // 5. 构造 AI prompt
            StringBuilder systemPrompt = new StringBuilder();
            systemPrompt.append("你是图书馆的智能推荐助手，请根据列表推荐一本图书，只能根据列表已经有的，输出结构化 JSON 格式如下：\\n")
                    .append("{\\n  \"book\": \"推荐书名\",\\n  \"reason\": \"推荐理由\"\\n}\\n")
                    .append("用户正在查阅《").append(bookTitle).append("》，以下是同类书籍：\n");

            for (Book book : recommendedBooks) {
                systemPrompt.append("- 《").append(book.getName()).append("》\n");
            }

            List<ChatRequest.Message> messages = new ArrayList<>();
            messages.add(new ChatRequest.Message("system", systemPrompt.toString()));
            messages.add(new ChatRequest.Message("user", "请推荐一本类似的书，输出 JSON 格式。"));

            ChatRequest request = ChatRequest.builder()
                    .model(deepSeekConfig.getModel())
                    .temperature(deepSeekConfig.getTemperature())
                    .max_tokens(deepSeekConfig.getMaxTokens())
                    .messages(messages)
                    .build();

            HttpResponse execute = HttpUtil.createRequest(Method.POST, deepSeekConfig.getApiUrl())
                    .body(JSONUtil.toJsonStr(request))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + deepSeekConfig.getApiKey())
                    .header("Accept", "application/json")
                    .execute();

            String resp = execute.body();
            log.info("deepseek response: {}", resp);

            ChatResponse chatResponse = JSONUtil.toBean(resp, ChatResponse.class);
            String content = extractResponse(chatResponse);
            log.info("AI 返回原始内容：{}", content);

            // 删除代码块标记并清理空格
            String cleanJson = content.replace("```json", "").replace("```", "").trim();
            log.info("清理后的JSON内容：{}", cleanJson);

            try {
                cn.hutool.json.JSONObject jsonObject = cn.hutool.json.JSONUtil.parseObj(cleanJson);
                // 创建推荐对象并正确设置字段
                Recommendation recommendation = new Recommendation();
                recommendation.setTitle(jsonObject.getStr("book"));
                recommendation.setDescription(jsonObject.getStr("reason"));
                QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
                // 去除《》
                String cleandBookTitle = recommendation.getTitle().replace("《", "").replace("》", "");
                queryWrapper.like("name", cleandBookTitle);
                List<Book> books = bookMapper.selectList(queryWrapper);
                Book book = (books != null && !books.isEmpty()) ? books.get(0) : null;
                recommendation.setBook(book);
                log.info("推荐结果：{}", recommendation);
                log.info("书籍的详情信息{}", book);
                return recommendation;
            } catch (cn.hutool.json.JSONException e) {
                log.error("返回内容不是合法的 JSON 格式");
                return new Recommendation("推荐失败", "返回内容不是合法的 JSON 格式");
            }
        } catch (Exception e) {
            log.error("生成推荐失败：{}", bookTitle, e);
            return new Recommendation("推荐失败", "系统错误，推荐失败");
        }
    }



    private String extractResponse(ChatResponse response) {
        return Optional.ofNullable(response)
                .map(ChatResponse::getChoices)
                .filter(choices -> !choices.isEmpty())
                .map(choices -> choices.get(0))
                .map(choice -> choice.getMessage().getContent())
                .orElse("{}");
    }
}
